module ysyx_22040213_IDU(
	input [31:0] inst,
	output [4:0] rs1,
	output [4:0] rs2,
	output [4:0] rd,
	output [2:0] funct3,
	output [6:0] funct7,
	output [6:0] opcode,
	output [63:0] shamt,
	output [11:0] csr_rs1,
	output [11:0] csr_waddr,
	output mret,
	output ecall,
	output csrrw,
	output csrrs,
	output rem,
	output remu,
	output remuw,
	output remw,
	output div,
	output divu,
	output divuw,
	output divw,
	output mul,
	output mulw,
	output reg [63:0] ext_imm
);
wire [11:0] imm;
wire [11:0] immS;
wire [19:0] immU;
wire [12:0] immB;
wire [20:0] jumpoffset;

	assign opcode = inst[6:0];
	assign rd = inst[11:7];
	assign funct3 = inst[14:12];
	assign funct7 = inst[31:25];
	assign rs1 = inst[19:15];
	assign rs2 = inst[24:20];
	assign imm = inst[31:20];
	assign immU = inst[31:12];
	assign immS = {inst[31:25],inst[11:7]};
	assign jumpoffset = {inst[31],inst[19:12],inst[20], inst[30:21], {1'b0}};
	assign shamt = {{58'b0},inst[25:20]};
	assign immB =  {inst[31],inst[7],inst[30:25], inst[11:8], {1'b0}};
	import "DPI-C" function void NPCTRAP ();
	import "DPI-C" function void ftrace ();

	assign ecall = (opcode == 7'b1110011) && (imm == 12'b0) && (funct3 == 3'b0);
	assign mret  = (inst == 32'b00110000001000000000000001110011);
	assign csrrw = (opcode == 7'b1110011) && (funct3 == 3'b001);
	assign csrrs = (opcode == 7'b1110011) && (funct3 == 3'b010);

	assign rem   = (funct7 == 7'b0000001) && (opcode == 7'b0110011) && (funct3 == 3'b110);
	assign remu  = (funct7 == 7'b0000001) && (opcode == 7'b0110011) && (funct3 == 3'b111);
	assign remuw = (funct7 == 7'b0000001) && (opcode == 7'b0111011) && (funct3 == 3'b111);
	assign remw  = (funct7 == 7'b0000001) && (opcode == 7'b0111011) && (funct3 == 3'b110);

	assign div   = (funct7 == 7'b0000001) && (opcode == 7'b0110011) && (funct3 == 3'b100); 
	assign divu  = (funct7 == 7'b0000001) && (opcode == 7'b0110011) && (funct3 == 3'b101); 
	assign divw  = (funct7 == 7'b0000001) && (opcode == 7'b0111011) && (funct3 == 3'b100); 
	assign divuw = (funct7 == 7'b0000001) && (opcode == 7'b0111011) && (funct3 == 3'b101); 
	
	assign mul   = (funct7 == 7'b0000001) && (opcode == 7'b0110011) && (funct3 == 3'b000); 
	assign mulw  = (funct7 == 7'b0000001) && (opcode == 7'b0111011) && (funct3 == 3'b000); 
	
	assign csr_rs1 = csrrw || csrrs ? imm : 12'b0;
	assign csr_waddr = ecall ? 12'h305 : csrrw ? imm : 12'b0;
always @(*)begin
	ext_imm = 64'b0;
	case (opcode)
		7'b0010011 ://I-type
		begin
			ext_imm = {{52{imm[11]}},imm};
		end
		7'b0011011 ://I-type word addiw
		begin
			ext_imm = {{52{imm[11]}},imm};
		end
		7'b0010111 : //U-type
		begin
			ext_imm = {{32{immU[19]}},immU,{12'b0}};
		end
		7'b0110111 : //U-type lui
		begin
			ext_imm = {{32{immU[19]}},immU,{12'b0}};
		end
		7'b1101111 : //jal
		begin
			ext_imm =  {{43{jumpoffset[20]}},jumpoffset}; 
			ftrace();
		end
		7'b1100111 : //jalr ret
		begin
			ext_imm = {{52{imm[11]}},imm};
			ftrace();
		end
		7'b0100011 : //S-type
		begin
			ext_imm = {{52{immS[11]}},immS};
		end
		7'b0000011 : //lbu
		begin
			ext_imm = {{52{imm[11]}},imm};
		end
		7'b1100011 : //B-type
		begin
			ext_imm = {{51{immB[12]}},immB};
		end
		7'b0110011 : //R-type
		begin

		end
		7'b1110011 : 
		begin  
		  if(imm == 12'b1)begin //ebreak
		    NPCTRAP;
		  end else if(imm == 12'b0)begin//ecall
//		    NPCTRAP;
		  end else begin
		  end
		end
		  default : ext_imm = 64'b0;
	endcase
end

endmodule


